﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using WHControlLib.CommonHelpers;

namespace WHControlLib.Controls
{
    [ToolboxItem(true)]
    [DefaultEvent("ValueChanged")]
    [DefaultProperty("Value")]
    public partial class WHUpDown : UserControl
    {
        public WHUpDown()
        {   //设置双缓冲开启禁止背景擦拭
            SetStyle(
                     ControlStyles.OptimizedDoubleBuffer
                     | ControlStyles.ResizeRedraw
                     | ControlStyles.Selectable
                     | ControlStyles.AllPaintingInWmPaint
                     | ControlStyles.UserPaint
                     | ControlStyles.SupportsTransparentBackColor,
                     true);


            ////背景定义为透明色   
            SetStyle(ControlStyles.SupportsTransparentBackColor, true);
            //BackColor = Color.Transparent;

            InitializeComponent();
        }
        Rectangle DrawRect = new Rectangle();
        Rectangle MyRect = new Rectangle();
        Rectangle UpRect = new Rectangle();
        Rectangle DownRect = new Rectangle();
        Rectangle OnMouseDownRect = new Rectangle();
        int ClickButton = 0;

        [DllImport("user32.dll")]
        public static extern bool HideCaret(IntPtr hWnd);

        #region 自定义事件定义
        [Category("A我的事件"), Description("当值改变时候发生"), Browsable(true)]
        public event EventHandler ValueChanged;    
           
        #endregion

        public enum UpDownShape
        {
            Squre, Circle
        }

        #region 属性定义

        private bool _isShowBorder;
        [Category("A我的"), Description("是否显示边框，默认 否"), Browsable(true)]
        public bool IsShowBorder
        {
            get { return _isShowBorder; }
            set { _isShowBorder = value; Invalidate(); }
        }
        private Color _borderColor = Color.Blue;
        [Category("A我的"), Description("边框颜色，默认 蓝色"), Browsable(true)]
        public Color BorderColor
        {
            get { return _borderColor; }
            set { _borderColor = value; Invalidate(); }
        }
        private float _borderWidth = 2.0f;
        [Category("A我的"), Description("边框宽度，默认 2.0f"), Browsable(true)]
        public float BorderWidth
        {
            get { return _borderWidth; }
            set
            {
                if (value < 1)
                {
                    _borderWidth = 1.0f;
                }
                else
                    _borderWidth = value;
                Invalidate();

            }
        }



        private bool _isFillButton = true;
        [Category("A我的"), Description("是否填充增减按钮的内部颜色，默认 是"), Browsable(true)]
        public bool IsFillButton
        {
            get { return _isFillButton; }
            set { _isFillButton = value; Invalidate(); }
        }
        private Color _buttonFillColor = Color.White;
        [Category("A我的"), Description("填充增减按钮的内部颜色，默认 白色"), Browsable(true)]
        public Color ButtonFillColor
        {
            get { return _buttonFillColor; }
            set { _buttonFillColor = value; Invalidate(); }


        }
        private Color _mouseDownButtonFillColor = Color.Orange;
        [Category("A我的"), Description("填充增减按钮按下时的内部颜色，默认 橙色"), Browsable(true)]
        public Color MouseDownButtonFillColor
        {
            get { return _mouseDownButtonFillColor; }
            set { _mouseDownButtonFillColor = value; Invalidate(); }


        }

        private bool _isShowUpDownButton=true;
        [Category("A我的"), Description("是否显示增减按钮，默认 true"), Browsable(true)]
        public bool IsShowUpDownButton
        {
            get { return _isShowUpDownButton; }
            set { _isShowUpDownButton = value; Invalidate(); }
        }


        private bool _isDrawButtonBorder;
        [Category("A我的"), Description("是否绘制增减按钮的外形边框，默认 否"), Browsable(true)]
        public bool IsDrawButtonBorder
        {
            get { return _isDrawButtonBorder; }
            set { _isDrawButtonBorder = value; Invalidate(); }
        }
        private Color _buttonBorderColor = Color.Red;
        [Category("A我的"), Description("增减按钮的边框颜色颜色，默认 红色"), Browsable(true)]
        public Color ButtonBorderColor
        {
            get { return _buttonBorderColor; }
            set { _buttonBorderColor = value; Invalidate(); }
        }
        private float _buttonBorderWidth = 2.0f;
        [Category("A我的"), Description("增减按钮的边框宽度，默认 2.0f"), Browsable(true)]
        public float ButtonBorderWidth
        {
            get { return _buttonBorderWidth; }
            set
            {
                if (value < 1.0f)
                {
                    _buttonBorderWidth = 1.0f;
                }
                else
                    _buttonBorderWidth = value; Invalidate();
            }
        }
        private UpDownShape _myUpDownShape = UpDownShape.Circle;
        [Category("A我的"), Description("增减按钮的形状，默认 原型"), Browsable(true)]
        public UpDownShape MyUpDownShape
        {
            get { return _myUpDownShape; }
            set { _myUpDownShape = value; Invalidate(); }
        }

        private float _signWidthBL = 8;
        [Category("A我的"), Description("增减按钮加减号的大小，默认8，即大小的1/8 不能小于2"), Browsable(true)]
        public float SignWidthBL
        {
            get { return _signWidthBL; }
            set
            {
                if (value < 2.0f)
                    _signWidthBL = 2.0f;
                else
                    _signWidthBL = value; Invalidate();
            }
        }
        private Color _signColor = Color.Black;
        [Category("A我的"), Description("增减按钮加减号的颜色，默认黑色，"), Browsable(true)]
        public Color SignColor
        {
            get { return _signColor; }
            set { _signColor = value; Invalidate(); }
        }
        bool FirstStar;
        private float _value = 0f;
        [Category("A我的"), Description("当前的浮点值，0，"), Browsable(true)]
        public float Value
        {
            get { return _value; }
            set {
                _value = value;
                    Invalidate();
               
                 if (ValueChanged != null)
                {
                    ValueChanged(this, EventArgs.Empty);
                }
                textBox1.Text = value.ToString();


                }
        }
        private float _step = 1f;
        [Category("A我的"), Description("每次增加或减少的值，默认1.0f，"), Browsable(true)]
        public float Step
        {
            get { return _step; }
            set { _step = value; }
        }
        private Font _valueFont= new Font("微软雅黑", 10.0f, 0, GraphicsUnit.Point, 1);
        [Category("A我的"), Description("显示值的字体，微软雅黑，"), Browsable(true)]
        public Font ValueFont
        {
            get { return _valueFont; }
            set {
                _valueFont = value;
                textBox1.Font=_valueFont ;
                Invalidate(); }
        }
        private Color _valueColor=Color.Black;
        [Category("A我的"), Description("显示值的字体颜色，默认 黑]色，"), Browsable(true)]
        public Color ValueColor
        {
            get { return _valueColor; }
            set  {
                if (value!=Color.Transparent)
                {
                 _valueColor = value;
                textBox1.ForeColor = _valueColor;
                Invalidate();
                }
               }
        }
        private bool _isShowTextBorder=true;
        [Category("A我的"), Description("是否显示文本框的边线，默认 true，"), Browsable(true)]
        public bool IsShowTextBorder
        {
            get { return _isShowTextBorder; }
            set
            {
                if (value)
                {
                    textBox1.BorderStyle = BorderStyle.FixedSingle;
                }
                else textBox1.BorderStyle = BorderStyle.None;
                _isShowTextBorder = value; Invalidate();
            }
        }
        private Color _valueBackColor=Color.White;
        [Category("A我的"), Description("文本框的背景色，默认 白色，"), Browsable(true)]
        public Color ValueBackColor
        {
            get { return _valueBackColor; }
            set
            {
                if (value!=Color.Transparent)
                {
                textBox1.BackColor = value; 
                _valueBackColor = value; Invalidate();
                }

            }
        }


        #endregion

        void BeginPaintIni()
        {
            MyRect = this.ClientRectangle;

            int UpDownHeight = Math.Min(MyRect.Height, MyRect.Width) / 3 * 2;


            DownRect.Height = UpDownHeight;
            DownRect.Width = UpDownHeight;
            DownRect.X = MyRect.X + 5;
            DownRect.Y = MyRect.Y + (int)(MyRect.Height / 2 - UpRect.Height / 2);



            UpRect.Height = DownRect.Height;

            UpRect.Width = DownRect.Width;
            UpRect.X = MyRect.Right - UpRect.Width - 5;
            UpRect.Y = DownRect.Y;

            textBox1.Height = UpDownHeight;
            textBox1.Width = MyRect.Width - DownRect.Width - UpRect.Width - 20;
            textBox1.Left = MyRect.Left + DownRect.Left + DownRect.Width + 5;
            textBox1.Top = (MyRect.Height - textBox1.Height) / 2;

        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            textBox1.AutoSize = false;


            textBox1.GotFocus +=  textBox1_GotFocus;
            textBox1.LostFocus += textBox1_LostFocus;
            textBox1.TabStop = false;

            textBox1.MouseDown +=  textBox1_MouseDown;

            BeginPaintIni();
        }
        void textBox1_GotFocus(object sender, EventArgs e)
        {
            HideCaret((sender as TextBox).Handle);
        }
        void textBox1_LostFocus(object sender, EventArgs e)
        {
           //(sender as TextBox).Select(0,0);
        }

        private void textBox1_MouseDown(object sender, MouseEventArgs e)
        {
            HideCaret((sender as TextBox).Handle); }


        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            BeginPaintIni();
            Graphics Myg = e.Graphics;
            Myg.SmoothingMode = SmoothingMode.AntiAlias;
            Myg.CompositingQuality = CompositingQuality.HighQuality;
            Myg.InterpolationMode = InterpolationMode.HighQualityBicubic;

           //是否需要画 增减按钮
            if (IsShowUpDownButton)
            {
                DrawUpDownButton(Myg, UpRect, DownRect);
            }
           


            //画控件整体边框
            if (IsShowBorder)
            {
                using (Pen p = new Pen(BorderColor, BorderWidth))
                {

                    Myg.DrawPath(p, DrawHelper.GetRoundRectangePath(MyRect, BorderWidth, 4));

                }

            }

        }


        protected override void OnMouseClick(MouseEventArgs e)
        {
            base.OnMouseClick(e);

           
        }

        private void AddOrMinusValue()
        {
            textBox1.Select(0, 0);
            if (RectangleToScreen(UpRect).Contains(MousePosition))
            {
                Value = Value + Step;
                textBox1.Text = (Value).ToString();

                return;

            }
            if (RectangleToScreen(DownRect).Contains(MousePosition))
            {
                Value = Value - Step;
                textBox1.Text = Value.ToString();
                return;
            }
        }

        protected override void OnMouseUp(MouseEventArgs e)
        {
            base.OnMouseUp(e);
            if (IsShowUpDownButton)
            {

            if (ClickButton == 1)
            {

                ClickButton = 0;
       
             
            }
            if (ClickButton == -1)
            {


                ClickButton = 0;
               
               
            }
            AddOrMinusValue();
          Invalidate();

            }
          
        }
        protected override void OnMouseDown(MouseEventArgs e)
        {
            base.OnMouseDown(e);
            if (RectangleToScreen(UpRect).Contains(MousePosition)&&IsShowUpDownButton)
            {
                ClickButton = 1;

                Invalidate();
                return;

            }
            if (RectangleToScreen(DownRect).Contains(MousePosition) && IsShowUpDownButton)
            {
                ClickButton = -1;

                Invalidate();
                return;
            }


        }
        void DrawAddSign(Graphics myg, Rectangle Rect, Color SignColor, float SignWidthBL)
        {
            int singWidth;


            if (Rect.Width != Rect.Height)
            {
                singWidth = (int)(Math.Min(Rect.Width, Rect.Height) / SignWidthBL);
            }
            else
                singWidth = (int)(Rect.Width / SignWidthBL);

            Rectangle Vrect = new Rectangle();
            Vrect.Width = singWidth;
            Vrect.Height = (int)(Rect.Height / 2);
            Vrect.X = Rect.X + (int)((Rect.Width - Vrect.Width) / 2);
            Vrect.Y = Rect.Y + Rect.Height / 4;
            Rectangle Hrect = new Rectangle();
            Hrect.Height = singWidth;
            Hrect.Width = (int)(Rect.Width / 2);
            Hrect.X = Rect.X + Rect.Width / 4;
            Hrect.Y = Rect.Y + (int)((Rect.Height - Hrect.Height) / 2);
            using (SolidBrush sb = new SolidBrush(SignColor))
            {
                myg.FillRectangle(sb, Vrect);
                myg.FillRectangle(sb, Hrect);
            }


        }
        void DrawMinusSign(Graphics myg, Rectangle Rect, Color SignColor, float SignWidthBL)
        {
            int singWidth;


            if (Rect.Width != Rect.Height)
            {
                singWidth = (int)(Math.Min(Rect.Width, Rect.Height) / SignWidthBL);
            }
            else
                singWidth = (int)(Rect.Width / SignWidthBL);
            Rectangle Hrect = new Rectangle();
            Hrect.Height = singWidth;
            Hrect.Width = (int)(Rect.Width / 2);
            Hrect.X = Rect.X + Rect.Width / 4;
            Hrect.Y = Rect.Y + (int)((Rect.Height - Hrect.Height) / 2);
            using (SolidBrush sb = new SolidBrush(SignColor))
            {

                myg.FillRectangle(sb, Hrect);
            }


        }
        void DrawUpDownButton(Graphics myg, Rectangle UpRect, Rectangle DownRect)
        {

            if (IsFillButton)
            {
                SolidBrush MouseDownsb = new SolidBrush(MouseDownButtonFillColor);

                using (SolidBrush shapeBrush = new SolidBrush(ButtonFillColor))
                {

                    switch (MyUpDownShape)
                    {
                        case UpDownShape.Squre:
                            if (ClickButton == 0)
                            {
                                myg.FillRectangle(shapeBrush, UpRect);
                                myg.FillRectangle(shapeBrush, DownRect);

                            }
                            if (ClickButton == 1)
                            {
                                myg.FillRectangle(MouseDownsb, UpRect);
                                myg.FillRectangle(shapeBrush, DownRect);


                            }
                            if (ClickButton == -1)
                            {
                                myg.FillRectangle(shapeBrush, UpRect);
                                myg.FillRectangle(MouseDownsb, DownRect);

                            }

                            break;
                        case UpDownShape.Circle:

                            if (ClickButton == 0)
                            {
                                myg.FillEllipse(shapeBrush, UpRect);
                                myg.FillEllipse(shapeBrush, DownRect);

                            }
                            if (ClickButton == 1)
                            {
                                myg.FillEllipse(MouseDownsb, UpRect);
                                myg.FillEllipse(shapeBrush, DownRect);


                            }
                            if (ClickButton == -1)
                            {
                                myg.FillEllipse(shapeBrush, UpRect);
                                myg.FillEllipse(MouseDownsb, DownRect);

                            }



                            break;
                        default:
                            break;
                    }

                    MouseDownsb.Dispose();
                }



            }

            if (IsDrawButtonBorder)
            {
                using (Pen btPen = new Pen(ButtonBorderColor, ButtonBorderWidth))
                {
                    switch (MyUpDownShape)
                    {
                        case UpDownShape.Squre:
                            myg.DrawRectangle(btPen, UpRect);
                            myg.DrawRectangle(btPen, DownRect);

                            break;
                        case UpDownShape.Circle:
                            myg.DrawEllipse(btPen, UpRect);
                            myg.DrawEllipse(btPen, DownRect);

                            break;
                        default:
                            break;
                    }
                }
            }


            DrawAddSign(myg, UpRect, SignColor, SignWidthBL);
            DrawMinusSign(myg, DownRect, SignColor, SignWidthBL);

        }
       

        private void textBox1_TextChanged(object sender, EventArgs e)
        {
            
          
            //}


            //////////////////////////////////
        }

        private void textBox1_Click(object sender, EventArgs e)
        {
            textBox1.SelectAll();
        }

        private void textBox1_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode==Keys.Enter)
            {
            if (!DataCheckHelper.isNumber(textBox1.Text))
            {

                textBox1.Text = Value.ToString();
                textBox1.SelectAll();
            }
            else
            {
                Value = Convert.ToSingle(textBox1.Text);

            }

            }
        }
    }
}
